#ifndef __GDB_H__
#define __GDB_H__
#include <nxos.h>

#ifndef __GDB_MAX_BREAKPOINTS_NUM_
#define __GDB_MAX_BREAKPOINTS_NUM_ 100
#endif

#ifndef __GDB_MAX_WATCHPOINTS_NUM_
#define __GDB_MAX_WATCHPOINTS_NUM_ 100
#endif

#define insert_break_or_watchpoint_software_breakpoint 0
#define insert_break_or_watchpoint_hardware_breakpoint 1
#define insert_break_or_watchpoint_write_watchpoint 2
#define insert_break_or_watchpoint_read_watchpoint 3
#define insert_break_or_watchpoint_access_watchpoint 4

#define gdb_c_ebreak_instruction 0x9002
#define gdb_ebreak_instruction 0x00100073

#define command_token_length 8

#define NX_USER_STACK_TOP     0x3FFFFF000UL         /* stack end */
#define NX_USER_STACK_VADDR   0x380000000UL         /* stack start */

typedef struct {
  NX_U64 en;
  NX_U8 type;
  NX_U64 addr;
  NX_I32 len;
  NX_U32 instruction;
} gdb_bkp_or_watch_t;

struct Registers{
    NX_UArch reg[32];
}NX_PACKED;
typedef struct Registers Registers;

struct FpRegisters{
    NX_UArch fp[32];
}NX_PACKED;
typedef struct fp_registers fp_registers;

enum GDB_REGISTER {
  GDB_CPU_RISCV_REG_X0 = 0,
  GDB_CPU_RISCV_REG_RA = 1,
  GDB_CPU_RISCV_REG_SP = 2,
  GDB_CPU_RISCV_REG_GP = 3,
  GDB_CPU_RISCV_REG_TP = 4,
  GDB_CPU_RISCV_REG_T0 = 5,
  GDB_CPU_RISCV_REG_T1 = 6,
  GDB_CPU_RISCV_REG_T2 = 7,
  GDB_CPU_RISCV_REG_S0 = 8,
  GDB_CPU_RISCV_REG_S1 = 9,
  GDB_CPU_RISCV_REG_A0 = 10,
  GDB_CPU_RISCV_REG_A1 = 11,
  GDB_CPU_RISCV_REG_A2 = 12,
  GDB_CPU_RISCV_REG_A3 = 13,
  GDB_CPU_RISCV_REG_A4 = 14,
  GDB_CPU_RISCV_REG_A5 = 15,
  GDB_CPU_RISCV_REG_A6 = 16,
  GDB_CPU_RISCV_REG_A7 = 17,
  GDB_CPU_RISCV_REG_S2 = 18,
  GDB_CPU_RISCV_REG_S3 = 19,
  GDB_CPU_RISCV_REG_S4 = 20,
  GDB_CPU_RISCV_REG_S5 = 21,
  GDB_CPU_RISCV_REG_S6 = 22,
  GDB_CPU_RISCV_REG_S7 = 23,
  GDB_CPU_RISCV_REG_S8 = 24,
  GDB_CPU_RISCV_REG_S9 = 25,
  GDB_CPU_RISCV_REG_S10 = 26,
  GDB_CPU_RISCV_REG_S11 = 27,
  GDB_CPU_RISCV_REG_T3 = 28,
  GDB_CPU_RISCV_REG_T4 = 29,
  GDB_CPU_RISCV_REG_T5 = 30,
  GDB_CPU_RISCV_REG_T6 = 31,
  GDB_CPU_RISCV_REG_PC = 32,
  GDB_CPU_NUM_REGISTERS = 33
};

struct reg_descriptor {
    enum GDB_REGISTER r;
    char *name;
};




void ReadCmd(char *cmd, int fd, int length);
void DbgRun(int fd, NX_Solt child);
void DbgHandleCommand(char *cmd, NX_Solt child);
int IsPrefix(const char *s, const char *ss);
int SetRegisterValue(NX_Solt tid, int reg, unsigned long long value);
int GetRegister(NX_Solt tid, Registers *regs);
#endif